import sys
import threading
import time
from PyQt5.QtWidgets import (
    QApplication, QWidget, QVBoxLayout, QHBoxLayout, QLineEdit,
    QLabel, QPushButton, QGroupBox, QFormLayout, QGridLayout,
)
from PyQt5.QtCore import pyqtSignal, QObject, QTimer

from sender import HighSpeedFrameTransmitter
from receiver import HighSpeedFrameReceiver
import config

from multiprocessing import Process,Queue

# =============== GUI 主窗口 ===============
class NetworkGui(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("WTSN TESTBENCH")
        self.resize(500, 400)

        # 数据队列
        self.sender_queue = Queue()
        self.receiver_queue = Queue()

        # 状态标志位
        self.running = False
        self.sender_thread = None
        self.receiver_thread = None

        self.init_ui()
        
        # 定时器轮询队列
        self.timer = QTimer()
        self.timer.timeout.connect(self.poll_queues)
        self.timer.start(200)  # 每200ms轮询

    # ------------------ UI 初始化 ------------------
    def init_ui(self):
        main_layout = QVBoxLayout(self)

        # 参数输入区域
        param_box = QGroupBox("参数设置")
        form = QFormLayout()

        self.iface1_edit = QLineEdit(config.INTERFACE1)
        self.iface2_edit = QLineEdit(config.INTERFACE2)
        self.mac1_edit = QLineEdit(config.INTERFACE1_MAC)
        self.mac2_edit = QLineEdit(config.INTERFACE2_MAC)
        self.frames_edit = QLineEdit(str(config.TEST_TOTAL_FRAMES))
        self.interval_edit = QLineEdit(str(config.INTERVAL_US))
        self.size_edit = QLineEdit(str(config.TEST_DATA_SIZE))
        self.eth_edit = QLineEdit(str(config.ETHERTYPE))

        form.addRow("发送网口:", self.iface1_edit)
        form.addRow("接收网口:", self.iface2_edit)
        form.addRow("发送MAC:", self.mac1_edit)
        form.addRow("接收MAC:", self.mac2_edit)
        form.addRow("帧数:", self.frames_edit)
        form.addRow("间隔(us):", self.interval_edit)
        form.addRow("数据长度:", self.size_edit)
        form.addRow("EthType:", self.eth_edit)

        param_box.setLayout(form)
        main_layout.addWidget(param_box)

        # 实时显示区
        self.status_box = QGroupBox("实时统计")
        grid = QGridLayout()

        self.send_frames = QLabel("已发帧数: 0")
        self.ber_label = QLabel("误比特率: 0.0")
        self.loss_label = QLabel("丢包率: 0.0")

        grid.addWidget(self.send_frames, 0, 0)
        grid.addWidget(self.ber_label, 1, 0)
        grid.addWidget(self.loss_label, 2, 0)

        self.status_box.setLayout(grid)
        main_layout.addWidget(self.status_box)

        # 控制按钮
        btn_layout = QHBoxLayout()
        self.start_btn = QPushButton("开始测试")
        self.stop_btn = QPushButton("停止测试")
        self.stop_btn.setEnabled(False)

        self.start_btn.clicked.connect(self.start_test)
        self.stop_btn.clicked.connect(self.stop_test)

        btn_layout.addWidget(self.start_btn)
        btn_layout.addWidget(self.stop_btn)
        main_layout.addLayout(btn_layout)

    # ------------------ 启动测试 ------------------
    def start_test(self):
        if self.running:
            return
        self.running = True
        self.start_btn.setEnabled(False)
        self.stop_btn.setEnabled(True)

        iface1 = self.iface1_edit.text()
        iface2 = self.iface2_edit.text()
        src_mac = self.mac1_edit.text()
        dest_mac = self.mac2_edit.text()
        frames = int(self.frames_edit.text())
        interval = int(self.interval_edit.text())
        size = int(self.size_edit.text())
        eth = int(self.eth_edit.text(), 16) if "0x" in self.eth_edit.text() else int(self.eth_edit.text())
        
        # 启动rx进程
        self.receiver_process = Process(
            target=self.run_receiver, 
            args=(iface2, size, frames, self.receiver_queue))
        self.receiver_process.start()
        time.sleep(0.5)
        # 启动tx进程
        self.sender_process = Process(
            target=self.run_sender, 
            args=(iface1, dest_mac, src_mac, frames, interval, size, eth,self.sender_queue))
        self.sender_process.start()


    # ------------------ 停止测试 ------------------
    def stop_test(self):
        self.running = False
        self.start_btn.setEnabled(True)
        self.stop_btn.setEnabled(False)
        if hasattr(self, "sender_process") and self.sender_process.is_alive():
            self.sender_process.terminate()
            self.sender_process.join()
        if hasattr(self, "receiver_process") and self.receiver_process.is_alive():
            self.receiver_process.terminate()
            self.receiver_process.join()

    # ------------------ 线程运行函数 ------------------
    def run_sender(self, iface, dest_mac, src_mac, frames, interval, size, eth, queue):
        sender = HighSpeedFrameTransmitter(iface, dest_mac, src_mac, frames, interval, size, eth)
        # 假设run_with_callback能接受普通回调
        sender.run_with_callback(lambda data: queue.put(data))

    def run_receiver(self, iface, size, frames, queue):
        receiver = HighSpeedFrameReceiver(iface, size, frames)
        receiver.run_with_callback(lambda stats: queue.put(stats))


    # ------------------ 定时器轮询 ------------------
    def poll_queues(self):
        while not self.receiver_queue.empty():
            recv_stats = self.receiver_queue.get()
            self.ber_label.setText(f"误比特率: {recv_stats['bit_error_rate']:.3e}")
            self.loss_label.setText(f"丢包率: {recv_stats['packet_loss_rate']:.3e}")
        while not self.sender_queue.empty():
            send_stats = self.sender_queue.get()
            self.send_frames.setText(f"已发帧数:  {send_stats["sent_frames"]}")


# ------------------ 主入口 ------------------
if __name__ == "__main__":
    app = QApplication(sys.argv)
    gui = NetworkGui()
    gui.show()
    sys.exit(app.exec_()) 
